<?php
class FileHelper {
	//recursively creates a folder.
	public static function mk_dir($path, $rights = 0777)
	{
		if (!@is_dir($path)) {
			$folder_path = array($path);
		} else {
			return;
		}

		while(!@is_dir(dirname(end($folder_path)))
		&& dirname(end($folder_path)) != '/'
		&& dirname(end($folder_path)) != '.'
		&& dirname(end($folder_path)) != '')
		{
			array_push($folder_path, dirname(end($folder_path)));
		}

		while($parent_folder_path = array_pop($folder_path)) {
			if(!@mkdir($parent_folder_path, $rights)) {
				user_error("Can't create folder \"$parent_folder_path\".\n");
			}
		}
	}


	public static function isMediaFile($extnFile)
	{
		$arrMediaMime = array(
				'audio/mpeg',
				'audio/basic',
				'audio/x-mpegurl',
				'audio/ogg',
				'audio/vorbis',
				'audio/x-ms-wma',
				'audio/midi',
				'audio/vnd.rn-realaudio',
				'audio/x-pn-realaudio',
				'audio/x-realaudio',
				'audio/x-pn-realaudio-plugin',
				'audio/x-wav',
				'audio/x-aiff',
				'video/mpeg',
				'video/mp4',
				'video/ogg',
				'video/quicktime',
				'video/x-ms-wmv',
				'video/vnd.mpegurl',
				'video/x-msvideo',
				'video/x-sgi-movie'        
				);

				$fileMime = self::findMime($extnFile);

				if(in_array($fileMime, $arrMediaMime)){
					return true;
				}else{
					return false;
				}
					
	}



	public static function findMime($ext) {
		// create mimetypes array
		$mimetypes = self::buildMimeArray();

		// return mime type for extension
		if (isset($mimetypes[$ext])) {
			return $mimetypes[$ext];
			// if the extension wasn't found return octet-stream
		} else {
			return 'application/octet-stream';
		}

	}

	public static function buildMimeArray() {
		return array(
			 "ez" => "application/andrew-inset",
			 "hqx" => "application/mac-binhex40",
			 "cpt" => "application/mac-compactpro",
			 "doc" => "application/msword",
			 "bin" => "application/octet-stream",
			 "dms" => "application/octet-stream",
			 "lha" => "application/octet-stream",
			 "lzh" => "application/octet-stream",
			 "exe" => "application/octet-stream",
			 "class" => "application/octet-stream",
			 "so" => "application/octet-stream",
			 "dll" => "application/octet-stream",
			 "oda" => "application/oda",
			 "pdf" => "application/pdf",
			 "ai" => "application/postscript",
			 "eps" => "application/postscript",
			 "ps" => "application/postscript",
			 "smi" => "application/smil",
			 "smil" => "application/smil",
			 "wbxml" => "application/vnd.wap.wbxml",
			 "wmlc" => "application/vnd.wap.wmlc",
			 "wmlsc" => "application/vnd.wap.wmlscriptc",
			 "bcpio" => "application/x-bcpio",
			 "vcd" => "application/x-cdlink",
			 "pgn" => "application/x-chess-pgn",
			 "cpio" => "application/x-cpio",
			 "csh" => "application/x-csh",
			 "dcr" => "application/x-director",
			 "dir" => "application/x-director",
			 "dxr" => "application/x-director",
			 "dvi" => "application/x-dvi",
			 "spl" => "application/x-futuresplash",
			 "gtar" => "application/x-gtar",
			 "hdf" => "application/x-hdf",
			 "js" => "application/x-javascript",
			 "skp" => "application/x-koan",
			 "skd" => "application/x-koan",
			 "skt" => "application/x-koan",
			 "skm" => "application/x-koan",
			 "latex" => "application/x-latex",
			 "nc" => "application/x-netcdf",
			 "cdf" => "application/x-netcdf",
			 "sh" => "application/x-sh",
			 "shar" => "application/x-shar",
			 "swf" => "application/x-shockwave-flash",
			 "sit" => "application/x-stuffit",
			 "sv4cpio" => "application/x-sv4cpio",
			 "sv4crc" => "application/x-sv4crc",
			 "tar" => "application/x-tar",
			 "tcl" => "application/x-tcl",
			 "tex" => "application/x-tex",
			 "texinfo" => "application/x-texinfo",
			 "texi" => "application/x-texinfo",
			 "t" => "application/x-troff",
			 "tr" => "application/x-troff",
			 "roff" => "application/x-troff",
			 "man" => "application/x-troff-man",
			 "me" => "application/x-troff-me",
			 "ms" => "application/x-troff-ms",
			 "ustar" => "application/x-ustar",
			 "src" => "application/x-wais-source",
			 "xhtml" => "application/xhtml+xml",
			 "xht" => "application/xhtml+xml",
			 "zip" => "application/zip",
			 "au" => "audio/basic",
			 "snd" => "audio/basic",
			 "mid" => "audio/midi",
			 "midi" => "audio/midi",
			 "kar" => "audio/midi",
			 "mpga" => "audio/mpeg",
			 "mp2" => "audio/mpeg",
			 "mp3" => "audio/mpeg",
			 "aif" => "audio/x-aiff",
			 "aiff" => "audio/x-aiff",
			 "aifc" => "audio/x-aiff",
			 "m3u" => "audio/x-mpegurl",
			 "ram" => "audio/x-pn-realaudio",
			 "rm" => "audio/x-pn-realaudio",
			 "rpm" => "audio/x-pn-realaudio-plugin",
			 "ra" => "audio/x-realaudio",
			 "wav" => "audio/x-wav",
			 "pdb" => "chemical/x-pdb",
			 "xyz" => "chemical/x-xyz",
			 "bmp" => "image/bmp",
			 "gif" => "image/gif",
			 "ief" => "image/ief",
			 "jpeg" => "image/jpeg",
			 "jpg" => "image/jpeg",
			 "jpe" => "image/jpeg",
			 "png" => "image/png",
			 "tiff" => "image/tiff",
			 "tif" => "image/tif",
			 "djvu" => "image/vnd.djvu",
			 "djv" => "image/vnd.djvu",
			 "wbmp" => "image/vnd.wap.wbmp",
			 "ras" => "image/x-cmu-raster",
			 "pnm" => "image/x-portable-anymap",
			 "pbm" => "image/x-portable-bitmap",
			 "pgm" => "image/x-portable-graymap",
			 "ppm" => "image/x-portable-pixmap",
			 "rgb" => "image/x-rgb",
			 "xbm" => "image/x-xbitmap",
			 "xpm" => "image/x-xpixmap",
			 "xwd" => "image/x-windowdump",
			 "igs" => "model/iges",
			 "iges" => "model/iges",
			 "msh" => "model/mesh",
			 "mesh" => "model/mesh",
			 "silo" => "model/mesh",
			 "wrl" => "model/vrml",
			 "vrml" => "model/vrml",
			 "css" => "text/css",
			 "html" => "text/html",
			 "htm" => "text/html",
			 "asc" => "text/plain",
			 "txt" => "text/plain",
			 "rtx" => "text/richtext",
			 "rtf" => "text/rtf",
			 "sgml" => "text/sgml",
			 "sgm" => "text/sgml",
			 "tsv" => "text/tab-seperated-values",
			 "wml" => "text/vnd.wap.wml",
			 "wmls" => "text/vnd.wap.wmlscript",
			 "etx" => "text/x-setext",
			 "xml" => "text/xml",
			 "xsl" => "text/xml",
			 "mpeg" => "video/mpeg",
			 "mpg" => "video/mpeg",
			 "mpe" => "video/mpeg",
			 "qt" => "video/quicktime",
			 "mov" => "video/quicktime",
			 "mxu" => "video/vnd.mpegurl",
			 "avi" => "video/x-msvideo",
			 "movie" => "video/x-sgi-movie",
			 "ice" => "x-conference-xcooltalk"
		  );
	}

/**
	 * Copies a directory recursively as another.
	 * If the destination directory does not exist, it will be created.
	 * @param string the source directory
	 * @param string the destination directory
	 * @param array options for directory copy. Valid options are:
	 * <ul>
	 * <li>fileTypes: array, list of file name suffix (without dot). Only files with these suffixes will be copied.</li>
	 * <li>exclude: array, list of directory and file exclusions. Each exclusion can be either a name or a path.
	 * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
	 * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
	 * file or directory '$src/a/b'.</li>
	 * <li>level: integer, recursion depth, default=-1.
	 * Level -1 means copying all directories and files under the directory;
	 * Level 0 means copying only the files DIRECTLY under the directory;
	 * level N means copying those directories that are within N levels.
 	 * </li>
	 * </ul>
	 */
	public static function copyDirectory($src,$dst,$options=array())
	{
		$fileTypes=array();
		$exclude=array();
		$level=-1;
		extract($options);
		self::copyDirectoryRecursive($src,$dst,'',$fileTypes,$exclude,$level);
	}

	/**
	 * Returns the files found under the specified directory and subdirectories.
	 * @param string the directory under which the files will be looked for
	 * @param array options for file searching. Valid options are:
	 * <ul>
	 * <li>fileTypes: array, list of file name suffix (without dot). Only files with these suffixes will be returned.</li>
	 * <li>exclude: array, list of directory and file exclusions. Each exclusion can be either a name or a path.
	 * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
	 * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
	 * file or directory '$src/a/b'.</li>
	 * <li>level: integer, recursion depth, default=-1.
	 * Level -1 means searching for all directories and files under the directory;
	 * Level 0 means searching for only the files DIRECTLY under the directory;
	 * level N means searching for those directories that are within N levels.
 	 * </li>
	 * </ul>
	 * @return array files found under the directory. The file list is sorted.
	 */
	public static function findFiles($dir,$options=array())
	{
		$fileTypes=array();
		$exclude=array();
		$level=-1;
		extract($options);
		$list=self::findFilesRecursive($dir,'',$fileTypes,$exclude,$level);
		sort($list);
		return $list;
	}

	/**
	 * Copies a directory.
	 * This method is mainly used by {@link copyDirectory}.
	 * @param string the source directory
	 * @param string the destination directory
	 * @param string the path relative to the original source directory
	 * @param array list of file name suffix (without dot). Only files with these suffixes will be copied.
	 * @param array list of directory and file exclusions. Each exclusion can be either a name or a path.
	 * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
	 * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
	 * file or directory '$src/a/b'.
	 * @param integer recursion depth. It defaults to -1.
	 * Level -1 means copying all directories and files under the directory;
	 * Level 0 means copying only the files DIRECTLY under the directory;
	 * level N means copying those directories that are within N levels.
	 */
	protected static function copyDirectoryRecursive($src,$dst,$base,$fileTypes,$exclude,$level)
	{
		@mkdir($dst);
		@chmod($dst,0777);
		$folder=opendir($src);
		while($file=readdir($folder))
		{
			if($file==='.' || $file==='..')
				continue;
			$path=$src.DIRECTORY_SEPARATOR.$file;
			$isFile=is_file($path);
			if(self::validatePath($base,$file,$isFile,$fileTypes,$exclude))
			{
				if($isFile)
					copy($path,$dst.DIRECTORY_SEPARATOR.$file);
				else if($level)
					self::copyDirectoryRecursive($path,$dst.DIRECTORY_SEPARATOR.$file,$base.'/'.$file,$fileTypes,$exclude,$level-1);
			}
		}
		closedir($folder);
	}

	/**
	 * Returns the files found under the specified directory and subdirectories.
	 * This method is mainly used by {@link findFiles}.
	 * @param string the source directory
	 * @param string the path relative to the original source directory
	 * @param array list of file name suffix (without dot). Only files with these suffixes will be returned.
	 * @param array list of directory and file exclusions. Each exclusion can be either a name or a path.
	 * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
	 * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
	 * file or directory '$src/a/b'.
	 * @param integer recursion depth. It defaults to -1.
	 * Level -1 means searching for all directories and files under the directory;
	 * Level 0 means searching for only the files DIRECTLY under the directory;
	 * level N means searching for those directories that are within N levels.
	 * @return array files found under the directory.
	 */
	protected static function findFilesRecursive($dir,$base,$fileTypes,$exclude,$level)
	{
		$list=array();
		$handle=opendir($dir);
		while($file=readdir($handle))
		{
			if($file==='.' || $file==='..')
				continue;
			$path=$dir.DIRECTORY_SEPARATOR.$file;
			$isFile=is_file($path);
			if(self::validatePath($base,$file,$isFile,$fileTypes,$exclude))
			{
				if($isFile)
					$list[]=$path;
				else if($level)
					$list=array_merge($list,self::findFilesRecursive($path,$base.'/'.$file,$fileTypes,$exclude,$level-1));
			}
		}
		closedir($handle);
		return $list;
	}

	/**
	 * Validates a file or directory.
	 * @param string the path relative to the original source directory
	 * @param string the file or directory name
	 * @param boolean whether this is a file
	 * @param array list of file name suffix (without dot). Only files with these suffixes will be copied.
	 * @param array list of directory and file exclusions. Each exclusion can be either a name or a path.
	 * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
	 * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
	 * file or directory '$src/a/b'.
	 * @return boolean whether the file or directory is valid
	 */
	protected static function validatePath($base,$file,$isFile,$fileTypes,$exclude)
	{
		foreach($exclude as $e)
		{
			if($file===$e || strpos($base.'/'.$file,$e)===0)
				return false;
		}
		if(!$isFile || empty($fileTypes))
			return true;
		if(($pos=strrpos($file,'.'))!==false)
		{
			$type=substr($file,$pos+1);
			return in_array($type,$fileTypes);
		}
		else
			return false;
	}
}
?>